// GoIM服务相关支持组件
package xim

import (
	"embed"

	"gitee.com/xiaoyutab/xgotool/optional/xsql"
	"gorm.io/gorm"
)

//go:embed sql/*
var sqlFile embed.FS

var sql xsql.Config = xsql.Config{}

// WebSocket组件，依赖于"github.com/gorilla/websocket"服务库
// 此处取名为XIM意为直接支持到IM通信
// 支持：
//  1. 同一用户的多设备通信
//  2. 用户与用户之间的通信
//  3. 多用户的群之间的通信
//
// 功能点：
//  1. 设备间通讯
//  2. 用户间通讯
//  3. 群通讯
//  4. 群公告
//  5. 群昵称
//  6. 群备注
//  7. 群免打扰
//  8. 群折叠
//  9. 群管理
//  10. 群禁言
//  11. 群成员禁言（单独禁言某个人）
//  12. 通讯录
//  13. 最近聊天
//
// 模块定义
type Config struct {
	DB                  *gorm.DB              // 数据库连接
	MessageTable        string                // 用户消息记录表
	ChatTable           string                // 聊天窗表【无论和谁聊天，都需要预先创建Chat聊天窗】
	ChatUserTable       string                // 聊天窗所属成员列表
	ChatFromTable       string                // 聊天窗和用户的关联表，此表定义了每个人的聊天窗中展示的记录
	UserDerviceTable    string                // 用户设备表
	UserDerviceMacTable string                // 用户设备网卡关联表
	UsersFrindsTable    string                // 用户好友关系表
	ChatsJoinTable      string                // 用户好友申请表
	DefaultDerviceThumb uint                  // 默认设备间通讯的默认图ID
	DefaultDerviceName  string                // 默认设备间通讯的群名称
	NsqMessageSend      string                // 消息发送队列通知
	GetUserNickname     func(uid uint) string // 获取用户昵称
	GetUserAvatar       func(uid uint) uint   // 获取用户头像
}

var _default Config = Config{
	MessageTable:        "im_message",
	ChatTable:           "im_chat",
	ChatUserTable:       "im_chat_user",
	ChatFromTable:       "im_chat_from",
	UserDerviceTable:    "im_user_dervice",
	UserDerviceMacTable: "im_user_dervice_mac",
	UsersFrindsTable:    "im_user_frinds",
	ChatsJoinTable:      "im_chats_join",
	DefaultDerviceThumb: 0,
	DefaultDerviceName:  "消息传输助手",
	GetUserNickname:     func(uid uint) string { return "" },
	GetUserAvatar:       func(uid uint) uint { return 0 },
}

// 配置注入函数，用于将配置信息注入到程序组件中
func Regedit(c *Config) {
	if c == nil {
		return
	}
	if c.GetUserNickname != nil {
		_default.GetUserNickname = c.GetUserNickname
	}
	if c.GetUserAvatar != nil {
		_default.GetUserAvatar = c.GetUserAvatar
	}
	if c.DB != nil {
		_default.DB = c.DB
	}
	if c.MessageTable != "" {
		_default.MessageTable = c.MessageTable
	}
	if c.DefaultDerviceName != "" {
		_default.DefaultDerviceName = c.DefaultDerviceName
	}
	if c.DefaultDerviceThumb > 0 {
		_default.DefaultDerviceThumb = c.DefaultDerviceThumb
	}
	if c.ChatTable != "" {
		_default.ChatTable = c.ChatTable
	}
	if c.ChatUserTable != "" {
		_default.ChatUserTable = c.ChatUserTable
	}
	if c.ChatFromTable != "" {
		_default.ChatFromTable = c.ChatFromTable
	}
	if c.UserDerviceTable != "" {
		_default.UserDerviceTable = c.UserDerviceTable
	}
	if c.UserDerviceMacTable != "" {
		_default.UserDerviceMacTable = c.UserDerviceMacTable
	}
	if c.NsqMessageSend != "" {
		_default.NsqMessageSend = c.NsqMessageSend
	}
	if _default.DB != nil {
		_default.DB.
			Set("gorm:table_options", "ENGINE=MyISAM").
			AutoMigrate(&Chat{}, &ChatUser{}, &ChatFrom{}, &Message{}, &ImUserDervice{}, &ImUserDerviceMac{})
	}
	sql.DB = _default.DB
	sql.SqlFile = &sqlFile
}

// Chat聊天窗/群/组结构体
type Chat struct {
	Id        uint64 `gorm:"column:id;primaryKey;type:BIGINT UNSIGNED;not null;autoIncrement" json:"id" form:"id"`
	UserId    uint   `gorm:"column:user_id;type:INT UNSIGNED;comment:创建人" json:"user_id" form:"user_id"`                                 //创建人【群主ID】
	TypeId    uint8  `gorm:"column:type_id;type:TINYINT UNSIGNED;comment:类型 1-设备间通信 2-用户间通信 3-群聊天" json:"type_id" form:"type_id"`        //类型 1-设备间通信 2-用户间通信 3-群聊天
	Thumb     uint   `gorm:"column:thumb;type:INT UNSIGNED;comment:缩略图" json:"thumb" form:"thumb"`                                       //缩略图
	Name      string `gorm:"column:name;type:VARCHAR(200);comment:名称" json:"name" form:"name"`                                           //名称
	Desc      string `gorm:"column:desc;type:VARCHAR(200);comment:简介/公告" json:"desc" form:"desc"`                                        //简介/公告
	IsDeleted uint8  `gorm:"column:is_deleted;type:TINYINT UNSIGNED;comment:是否删除 0-正常 1-删除" json:"is_deleted" form:"is_deleted"`         //是否删除 0-正常 1-删除
	IsSilence uint8  `gorm:"column:is_silence;type:TINYINT UNSIGNED;comment:是否禁言 开启禁言后将只允许群主、群管理发言" json:"is_silence" form:"is_silence"` //是否禁言 开启禁言后将只允许群主、群管理发言
	CreatedAt string `gorm:"column:created_at;type:DATETIME;comment:创建时间" json:"created_at" form:"created_at"`                           // 创建时间
}

// 表名称
func (c *Chat) TableName() string {
	return _default.ChatTable
}

// 群成员表
type ChatUser struct {
	Id                uint64 `gorm:"column:id;primaryKey;type:BIGINT UNSIGNED;not null;autoIncrement" json:"id" form:"id"`
	ChatId            uint64 `gorm:"column:chat_id;type:BIGINT UNSIGNED;not null" json:"chat_id" form:"chat_id"`                                             // 所属群ID
	UserId            uint   `gorm:"column:user_id;type:INT UNSIGNED;comment:用户ID" json:"user_id" form:"user_id"`                                            //用户ID
	DerviceId         uint   `gorm:"column:dervice_id;type:int unsigned;comment:所属设备ID，仅限设备间通讯使用" form:"dervice_id" json:"dervice_id"`                       //所属设备ID，仅限设备间通讯使用
	Desc              string `gorm:"column:desc;type:VARCHAR(200);comment:群备注，仅自己可见" json:"desc" form:"desc"`                                                //群备注
	Nickname          string `gorm:"column:nickname;type:VARCHAR(200);comment:群昵称，我在本群的昵称" json:"nickname" form:"nickname"`                                  //群昵称
	Thumb             uint   `gorm:"column:thumb;type:INT UNSIGNED;comment:缩略图" json:"thumb" form:"thumb"`                                                   //缩略图
	IsManagement      uint8  `gorm:"column:is_management;type:TINYINT UNSIGNED;comment:是否是群管理" json:"is_management" form:"is_management"`                    //是否是群管理
	IsUnInterruptions uint8  `gorm:"column:is_un_interruptions;type:TINYINT UNSIGNED;comment:是否开启免打扰" json:"is_un_interruptions" form:"is_un_interruptions"` //是否开启免打扰
	IsPack            uint8  `gorm:"column:is_pack;type:TINYINT UNSIGNED;comment:是否折叠收起" json:"is_pack" form:"is_pack"`                                      //是否折叠收起
	IsBook            uint8  `gorm:"column:is_book;type:TINYINT UNSIGNED;comment:是否显示在通讯录" json:"is_book" form:"is_book"`                                    //是否显示在通讯录
	IsSilence         uint8  `gorm:"column:is_silence;type:TINYINT UNSIGNED;comment:是否禁言" json:"is_silence" form:"is_silence"`                               //是否禁言
	IsDeleted         uint8  `gorm:"column:is_deleted;type:tinyint unsigned;comment:是否删除" form:"is_deleted" json:"is_deleted"`                               //是否删除
	CreatedAt         string `gorm:"column:created_at;type:DATETIME;comment:创建时间" json:"created_at" form:"created_at"`                                       // 加入时间
}

// 表名称
func (c *ChatUser) TableName() string {
	return _default.ChatUserTable
}

// 群和用户的关联
type ChatFrom struct {
	Id         uint64 `gorm:"column:id;primaryKey;type:BIGINT UNSIGNED;not null;autoIncrement" json:"id" form:"id"`
	ChatId     uint64 `gorm:"column:chat_id;type:BIGINT UNSIGNED;not null;comment:群ID" json:"chat_id" form:"chat_id"`                // 所属群ID
	UserId     uint   `gorm:"column:user_id;type:INT UNSIGNED;comment:用户ID" json:"user_id" form:"user_id"`                           //用户ID
	MessageId  uint64 `gorm:"column:message_id;type:BIGINT UNSIGNED;not null;comment:已读的最大消息ID" json:"message_id" form:"message_id"` // 已读消息ID【超过该ID的消息为未读状态】
	IsRecently uint8  `gorm:"column:is_recently;type:TINYINT UNSIGNED;comment:是否显示在最近聊天列表" json:"is_recently" form:"is_recently"`    //是否显示在最近聊天列表[删除时即将此值修改为0]
	IsTop      uint8  `gorm:"column:is_top;type:TINYINT UNSIGNED;comment:是否置顶" json:"is_top" form:"is_top"`                          //是否置顶[置顶后列表根据置顶群的消息聊天时间进行排序]
	CreatedAt  string `gorm:"column:created_at;type:DATETIME;comment:最近聊天时间" json:"created_at" form:"created_at"`                    // 最近聊天时间
	IsDeleted  uint8  `gorm:"column:is_deleted;type:tinyint unsigned;comment:是否删除" form:"is_deleted" json:"is_deleted"`              //是否删除
}

// 表名称
func (c *ChatFrom) TableName() string {
	return _default.ChatFromTable
}

// 消息记录
type Message struct {
	Id          uint64  `gorm:"column:id;primaryKey;type:BIGINT UNSIGNED;not null;autoIncrement" json:"id" form:"id"`
	ChatId      uint64  `gorm:"column:chat_id;type:BIGINT UNSIGNED;not null;comment:群ID" json:"chat_id" form:"chat_id"`      // 所属群ID
	DerviceId   uint    `gorm:"column:dervice_id;type:int unsigned;comment:所属设备ID" form:"dervice_id" json:"dervice_id"`      //所属设备ID
	UserId      uint    `gorm:"column:user_id;type:INT UNSIGNED;comment:发信人ID" json:"user_id" form:"user_id"`                //发信人ID
	Type        uint8   `gorm:"column:type;type:TINYINT UNSIGNED;comment:消息类型" json:"type" form:"type"`                      //消息类型 1-普通消息 2-图片消息 3-语音消息 4-视频消息 5-地址消息
	Message     string  `gorm:"column:message;type:VARCHAR(500);comment:消息内容" json:"message" form:"message"`                 //消息内容，最大限制500字节
	Fid         uint    `gorm:"column:fid;type:INT UNSIGNED;comment:附件ID" json:"fid" form:"fid"`                             //附件ID 图片/音频/视频文件所属的xfile.ID
	AddressCity uint    `gorm:"column:address_city;type:INT UNSIGNED;comment:省市区ID" json:"address_city" form:"address_city"` //省市区Code
	Address     string  `gorm:"column:address;type:VARCHAR(200);comment:地址信息" json:"address" form:"address"`                 //地址信息
	Latitude    float64 `json:"latitude" form:"latitude" gorm:"column:latitude;type:double;comment:纬度"`                      // 纬度  国内数值较小的数字4~53.5
	Longitude   float64 `json:"longitude" form:"longitude" gorm:"column:longitude;type:double;comment:经度"`                   // 经度  国内数值较大的数字73.5~135
	IsDeleted   uint8   `gorm:"column:is_deleted;type:tinyint unsigned;comment:是否删除" form:"is_deleted" json:"is_deleted"`    //是否删除
	CreatedAt   string  `gorm:"column:created_at;type:DATETIME;comment:发信时间" json:"created_at" form:"created_at"`            // 发信时间
}

// 表名称
func (c *Message) TableName() string {
	return _default.MessageTable
}

// 用户设备表
type ImUserDervice struct {
	Id           uint   `gorm:"column:id;type:int unsigned;primaryKey;autoIncrement;not null" form:"id" json:"id"`
	UserId       uint   `gorm:"column:user_id;type:int unsigned;comment:用户ID" form:"user_id" json:"user_id"`                       //用户ID
	Hostname     string `gorm:"column:hostname;type:varchar(100);comment:系统主机名（用户名）" form:"hostname" json:"hostname"`              //系统主机名（用户名）
	Goos         string `gorm:"column:goos;type:varchar(100);comment:系统名称 linux、drawin等" form:"goos" json:"goos"`                  //系统名称 linux、drawin等
	Arch         string `gorm:"column:arch;type:varchar(100);comment:操作系统架构" form:"arch" json:"arch"`                              //操作系统架构
	IsDeleted    uint8  `gorm:"column:is_deleted;type:tinyint unsigned;comment:是否删除" form:"is_deleted" json:"is_deleted"`          //是否删除
	IsLogin      uint8  `gorm:"column:is_login;type:tinyint unsigned;comment:是否已登陆" form:"is_login" json:"is_login"`               //是否已登录
	LastSendTime string `gorm:"column:last_send_time;type:datetime;comment:最后发言/心跳时间" form:"last_send_time" json:"last_send_time"` //最后发言/心跳时间
	CreatedAt    string `gorm:"column:created_at;type:datetime;comment:添加时间" form:"created_at" json:"created_at"`                  //添加时间
}

// 返回所属表名信息
func (c *ImUserDervice) TableName() string {
	return _default.UserDerviceTable
}

// 设备网卡MAC地址
type ImUserDerviceMac struct {
	Id        uint   `gorm:"column:id;type:int unsigned;primaryKey;autoIncrement;not null" form:"id" json:"id"`
	UserId    uint   `gorm:"column:user_id;type:int unsigned;comment:所属用户ID" form:"user_id" json:"user_id"`            //所属用户ID
	DerviceId uint   `gorm:"column:dervice_id;type:int unsigned;comment:所属设备ID" form:"dervice_id" json:"dervice_id"`   //所属设备ID
	MacName   string `gorm:"column:mac_name;type:varchar(100);comment:设备MAC地址所属名称" form:"mac_name" json:"mac_name"`    //设备MAC地址所属设备名称，如：eth0
	Mac       string `gorm:"column:mac;type:varchar(100);comment:设备MAC地址" form:"mac" json:"mac"`                       //设备MAC地址
	IsDeleted uint8  `gorm:"column:is_deleted;type:tinyint unsigned;comment:是否删除" form:"is_deleted" json:"is_deleted"` //是否删除
	CreatedAt string `gorm:"column:created_at;type:datetime;comment:添加时间" form:"created_at" json:"created_at"`         //添加时间
}

// 返回所属表名信息
func (c *ImUserDerviceMac) TableName() string {
	return _default.UserDerviceMacTable
}

// IM好友表，IM好友需要建立两条关系，即A的好友B和B的好友A这两条关系；而粉丝不需要
type UserFrinds struct {
	Id        uint   `gorm:"column:id;type:int unsigned;primaryKey;autoIncrement;not null" form:"id" json:"id"`
	UserId    uint   `gorm:"column:user_id;type:int unsigned;comment:所属用户ID" form:"user_id" json:"user_id"`             //所属用户ID
	FrindsId  uint   `gorm:"column:frinds_id;type:int unsigned;comment:好友ID" form:"frinds_id" json:"frinds_id"`         //好友ID
	Desc      string `gorm:"column:desc;type:varchar(200);comment:好友备注" form:"desc" json:"desc"`                        //好友备注
	TypeId    uint8  `gorm:"column:type_id;type:tinyint unsigned;comment:好友类型 1-好友 2-粉丝" form:"type_id" json:"type_id"` //好友类型 1-好友 2-粉丝
	CreatedAt string `gorm:"column:created_at;type:datetime;comment:创建时间" form:"created_at" json:"created_at"`          //创建时间
}

// 返回所属表名信息
func (c *UserFrinds) TableName() string {
	return _default.UsersFrindsTable
}

// 申请加好友、加群
type ChatsJoin struct {
	Id        uint   `gorm:"column:id;type:int unsigned;primaryKey;autoIncrement;not null" form:"id" json:"id"`
	UserId    uint   `gorm:"column:user_id;type:int unsigned;comment:用户ID" form:"user_id" json:"user_id"`                           //用户ID
	JoinId    uint   `gorm:"column:join_id;type:int unsigned;comment:加入对象ID" form:"join_id" json:"join_id"`                         //加入对象ID
	TypeId    uint8  `gorm:"column:type_id;type:tinyint unsigned;comment:加入类型 1-好友 2-群 3-邀请进群" form:"type_id" json:"type_id"`       //加入类型 1-好友 2-群 3-邀请进群
	Status    uint8  `gorm:"column:status;type:tinyint unsigned;comment:状态 1-待审核 2-审核忽略 3-审核拒绝 4-审核同意" form:"status" json:"status"` //状态 1-待审核 2-审核忽略 3-审核拒绝 4-审核同意
	CreatedAt string `gorm:"column:created_at;type:datetime;comment:申请时间" form:"created_at" json:"created_at"`                      //申请时间
	AutoAt    string `gorm:"column:auto_at;type:datetime;comment:审核时间" form:"auto_at" json:"auto_at"`                               //审核时间
}

// 返回所属表名信息
func (c *ChatsJoin) TableName() string {
	return _default.ChatsJoinTable
}

var reps [][]string

// SQL替换
//
//	index	要返回的类型 0-搜索字符串列表 1-替换字符串列表
func sqlRep(index int) []string {
	if reps == nil {
		reps = [][]string{
			{
				"`im_chat`",
				"`im_chat_from`",
				"`im_chat_user`",
				"`im_message`",
				"`im_user_dervice`",
				"`im_user_dervice_mac`",
				"`im_user_frinds`",
				"`im_chats_join`",
			}, {
				"`" + _default.ChatTable + "`",
				"`" + _default.ChatFromTable + "`",
				"`" + _default.ChatUserTable + "`",
				"`" + _default.MessageTable + "`",
				"`" + _default.UserDerviceTable + "`",
				"`" + _default.UserDerviceMacTable + "`",
				"`" + _default.UsersFrindsTable + "`",
				"`" + _default.ChatsJoinTable + "`",
			},
		}
	}
	if index == 0 {
		// 搜索
		return reps[0]
	}
	// 替换
	return reps[1]
}
